﻿using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;

namespace Chengqbd.Core.Common
{
    public class VerifyCodeHelper
	{
		private VerifyCodeHelper()
		{
		}
        
		public static VerifyCodeHelper GetSingleObj()
		{
			bool flag = VerifyCodeHelper._VerifyCodeHelper == null;
			if (flag)
			{
				object objLock = VerifyCodeHelper._ObjLock;
				lock (objLock)
				{
					bool flag3 = VerifyCodeHelper._VerifyCodeHelper == null;
					if (flag3)
					{
						VerifyCodeHelper._VerifyCodeHelper = new VerifyCodeHelper();
					}
				}
			}
			return VerifyCodeHelper._VerifyCodeHelper;
		}
        
		private string CreateNumberVerifyCode(int length)
		{
			int[] array = new int[length];
			int[] array2 = new int[length];
			string text = "";
			int seed = (int)DateTime.UtcNow.Ticks;
			Random random = new Random(seed);
			int num = random.Next(0, int.MaxValue - length * 10000);
			int[] array3 = new int[length];
			for (int i = 0; i < length; i++)
			{
				num += 10000;
				array3[i] = num;
			}
			for (int j = 0; j < length; j++)
			{
				Random random2 = new Random(array3[j]);
				int minValue = (int)Math.Pow(10.0, (double)length);
				array[j] = random2.Next(minValue, int.MaxValue);
			}
			for (int k = 0; k < length; k++)
			{
				string text2 = array[k].ToString();
				int length2 = text2.Length;
				Random random3 = new Random();
				int startIndex = random3.Next(0, length2 - 1);
				array2[k] = int.Parse(text2.Substring(startIndex, 1));
			}
			for (int l = 0; l < length; l++)
			{
				text += array2[l].ToString();
			}
			return text;
		}
        
		private string CreateAbcVerifyCode(int length)
		{
			char[] array = new char[length];
			char[] array2 = new char[]
			{
				'A',
				'B',
				'C',
				'D',
				'E',
				'F',
				'G',
				'H',
				'I',
				'J',
				'K',
				'L',
				'M',
				'N',
				'O',
				'P',
				'Q',
				'R',
				'S',
				'T',
				'U',
				'V',
				'W',
				'X',
				'Y',
				'Z',
				'a',
				'b',
				'c',
				'd',
				'e',
				'f',
				'g',
				'h',
				'i',
				'j',
				'k',
				'l',
				'm',
				'n',
				'o',
				'p',
				'q',
				'r',
				's',
				't',
				'u',
				'v',
				'w',
				'x',
				'y',
				'z'
			};
			Random random = new Random();
			for (int i = 0; i < length; i++)
			{
				array[i] = array2[random.Next(array2.Length - 1)];
			}
			return new string(array);
		}
        
		private string CreateMixVerifyCode(int length)
		{
			char[] array = new char[length];
			char[] array2 = new char[]
			{
				'A',
				'B',
				'C',
				'D',
				'E',
				'F',
				'G',
				'H',
				'I',
				'J',
				'K',
				'L',
				'M',
				'N',
				'O',
				'P',
				'Q',
				'R',
				'S',
				'T',
				'U',
				'V',
				'W',
				'X',
				'Y',
				'Z',
				'0',
				'1',
				'2',
				'3',
				'4',
				'5',
				'6',
				'7',
				'8',
				'9',
				'a',
				'b',
				'c',
				'd',
				'e',
				'f',
				'g',
				'h',
				'i',
				'j',
				'k',
				'l',
				'm',
				'n',
				'o',
				'p',
				'q',
				'r',
				's',
				't',
				'u',
				'v',
				'w',
				'x',
				'y',
				'z'
			};
			Random random = new Random();
			for (int i = 0; i < length; i++)
			{
				array[i] = array2[random.Next(array2.Length - 1)];
			}
			return new string(array);
		}
        /// <summary>
        /// 生成随机验证码
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
		public string CreateVerifyCode(VerifyCodeHelper.VerifyCodeType type)
		{
			string result = string.Empty;
			Random random = new Random();
			int length = random.Next(4, 6);
			switch (type)
			{
			case VerifyCodeHelper.VerifyCodeType.NumberVerifyCode:
				result = VerifyCodeHelper.GetSingleObj().CreateNumberVerifyCode(length);
				break;
			case VerifyCodeHelper.VerifyCodeType.AbcVerifyCode:
				result = VerifyCodeHelper.GetSingleObj().CreateAbcVerifyCode(length);
				break;
			case VerifyCodeHelper.VerifyCodeType.MixVerifyCode:
				result = VerifyCodeHelper.GetSingleObj().CreateMixVerifyCode(length);
				break;
			}
			return result;
		}
        /// <summary>
        /// 生成图片验证码
        /// </summary>
        /// <param name="verifyCode"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <returns></returns>
		public Bitmap CreateBitmapByImgVerifyCode(string verifyCode, int width, int height)
		{
			Font font = new Font("Arial", 14f, FontStyle.Bold | FontStyle.Italic);
			Bitmap bitmap = new Bitmap(width, height);
			Graphics graphics = Graphics.FromImage(bitmap);
			SizeF sizeF = graphics.MeasureString(verifyCode, font);
			PointF point = new PointF(0f, ((float)height - sizeF.Height) / 2f);
			Random random = new Random();
			graphics.Clear(Color.White);
			for (int i = 0; i < verifyCode.Length; i++)
			{
				Brush brush = new LinearGradientBrush(new Point(0, 0), new Point(1, 1), Color.FromArgb(random.Next(255), random.Next(255), random.Next(255)), Color.FromArgb(random.Next(255), random.Next(255), random.Next(255)));
				graphics.DrawString(verifyCode[i].ToString(), font, brush, point);
				SizeF sizeF2 = graphics.MeasureString(verifyCode[i].ToString(), font);
				point.X += sizeF2.Width;
			}
			for (int j = 0; j < 10; j++)
			{
				int x = random.Next(bitmap.Width);
				int x2 = random.Next(bitmap.Width);
				int y = random.Next(bitmap.Height);
				int y2 = random.Next(bitmap.Height);
				graphics.DrawLine(new Pen(Color.Silver), x, y, x2, y2);
			}
			for (int k = 0; k < 100; k++)
			{
				int x3 = random.Next(bitmap.Width);
				int y3 = random.Next(bitmap.Height);
				bitmap.SetPixel(x3, y3, Color.FromArgb(random.Next()));
			}
			graphics.DrawRectangle(new Pen(Color.Silver), 0, 0, bitmap.Width - 1, bitmap.Height - 1);
			graphics.Dispose();
			return bitmap;
		}
        /// <summary>
        /// 流方式生成验证码
        /// </summary>
        /// <param name="verifyCode"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <returns></returns>
		public byte[] CreateByteByImgVerifyCode(string verifyCode, int width, int height)
		{
			Font font = new Font("Arial", 14f, FontStyle.Bold | FontStyle.Italic);
			Bitmap bitmap = new Bitmap(width, height);
			Graphics graphics = Graphics.FromImage(bitmap);
			SizeF sizeF = graphics.MeasureString(verifyCode, font);
			PointF point = new PointF(0f, ((float)height - sizeF.Height) / 2f);
			Random random = new Random();
			graphics.Clear(Color.White);
			for (int i = 0; i < verifyCode.Length; i++)
			{
				Brush brush = new LinearGradientBrush(new Point(0, 0), new Point(1, 1), Color.FromArgb(random.Next(255), random.Next(255), random.Next(255)), Color.FromArgb(random.Next(255), random.Next(255), random.Next(255)));
				graphics.DrawString(verifyCode[i].ToString(), font, brush, point);
				SizeF sizeF2 = graphics.MeasureString(verifyCode[i].ToString(), font);
				point.X += sizeF2.Width;
			}
			for (int j = 0; j < 10; j++)
			{
				int x = random.Next(bitmap.Width);
				int x2 = random.Next(bitmap.Width);
				int y = random.Next(bitmap.Height);
				int y2 = random.Next(bitmap.Height);
				graphics.DrawLine(new Pen(Color.Silver), x, y, x2, y2);
			}
			for (int k = 0; k < 100; k++)
			{
				int x3 = random.Next(bitmap.Width);
				int y3 = random.Next(bitmap.Height);
				bitmap.SetPixel(x3, y3, Color.FromArgb(random.Next()));
			}
			graphics.DrawRectangle(new Pen(Color.Silver), 0, 0, bitmap.Width - 1, bitmap.Height - 1);
			graphics.Dispose();
			MemoryStream memoryStream = new MemoryStream();
			bitmap.Save(memoryStream, ImageFormat.Jpeg);
			return memoryStream.ToArray();
		}
        
		private static readonly object _ObjLock = new object();
        
		private static VerifyCodeHelper _VerifyCodeHelper = null;
        
		public enum VerifyCodeType
		{
			NumberVerifyCode,

			AbcVerifyCode,

			MixVerifyCode
		}
	}
}
